#include <iostream>

#include <fstream>

#include <stdlib.h>

#include <string>

#include <sstream>

#include <memory>

#include <jsoncpp/json/json.h>

int main(){

/*      序列化
 *  char *name = "小明";
 *  int age = 18;
 *  float score[] = {78.5,89,99}
 *
 *  1. 将所有数据保存在Json::Value中
 *  2. 使用Json::StreamWriter , Json::StreamWriterBuilder 进行序列化与反序列化
 *      序列化采用接口 write:
 *      virtual int write(Value const& root, std::ostream* out) = 0
 *      其中 std::ostream* out 能够使用 std::stringstream 进行序列化;
 * */

    // 已有数据
    const char *name = "小明";
    int age = 18;
    float score[] = {78.5,89,99};

    // 实例化一个Json::Value对象
    Json::Value root;

    // 将数据存储至Json实例中 可以直接使用赋值
    root["姓名"] = name ;
    root["年龄"] = age ; 
    for(unsigned int i = 0;i<sizeof(score)/sizeof(float);++i){
        root["成绩"].append(score[i]);
    }

    // 序列化
    Json::StreamWriterBuilder swb;
    // swb.settings_["emitUTF8"] = true;
        /* Jsoncpp 默认行为 非ASCII字符会转义为Unicode */
        /* 改为采用UTF-8的形式进行序列化而不采用Uincode */
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    std::stringstream ss;
    sw->write(root,&ss);
    std::cout<<ss.str()<<std::endl;

    std::cout<<std::endl;

/*
 *      反序列化:
 *      反序列首先需要有一个字符串 这个字符串为一个Json格式的字符串
 *      Jsoncpp中进行反序列化是将字符串中的数据解析放到对应的Json::Value中
 *          1. 定义一个Json::Value
 *          2. 借助Json::CharReaderBuilder,Json::CharReader类完成反序列化
 *          调用CharReader中的bool parse()成员函数进行反序列化
 *          bool parse(char const*beginDoc, char const* endDoc, Value* root,
 *          std::string* errs) = 0;
 *
 * */
    // 反序列化
    std::string str = ss.str();
    std::string strerr;
    Json::Value root2;
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    bool ret = cr->parse(str.c_str(),str.c_str()+str.size(),&root2,&strerr);
    if(ret == false){
        std::cout<<"Encode Error: "<<strerr<<std::endl;
        exit(-1);
    }
    std::cout<<root2["姓名"].asString()<<std::endl;
    std::cout<<root2["年龄"].asInt()<<std::endl;
    
    int sz = root2["成绩"].size();
    for(int i = 0;i<sz;++i){
        std::cout<<root2["成绩"][i]<<" ";
    }
    std::cout<<std::endl;
    return 0;
}
